home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / pyshared / gnutls / crypto.py < prev    next >
Encoding:
Python Source  |  2009-01-13  |  11.4 KB  |  318 lines

  1. # Copyright (C) 2007 AG Projects. See LICENSE for details.
  2. #
  3.  
  4. """GNUTLS crypto support"""
  5.  
  6. __all__ = ['X509Name', 'X509Certificate', 'X509PrivateKey', 'X509Identity', 'X509CRL', 'DHParams', 'RSAParams']
  7.  
  8. import re
  9. from ctypes import *
  10.  
  11. from gnutls.validators import method_args, one_of
  12. from gnutls.constants import X509_FMT_DER, X509_FMT_PEM
  13. from gnutls.errors import *
  14.  
  15. from gnutls.library.constants import GNUTLS_SAN_DNSNAME, GNUTLS_SAN_RFC822NAME, GNUTLS_SAN_URI
  16. from gnutls.library.constants import GNUTLS_SAN_IPADDRESS, GNUTLS_SAN_OTHERNAME, GNUTLS_SAN_DN
  17. from gnutls.library.constants import GNUTLS_E_SHORT_MEMORY_BUFFER
  18. from gnutls.library.types     import *
  19. from gnutls.library.functions import *
  20.  
  21.  
  22. class X509NameMeta(type):
  23.     long_names = {'country': 'C',
  24.                   'state': 'ST',
  25.                   'locality': 'L',
  26.                   'common_name': 'CN',
  27.                   'organization': 'O',
  28.                   'organization_unit': 'OU',
  29.                   'email': 'EMAIL'}
  30.     def __new__(cls, name, bases, dic):
  31.         instance = type.__new__(cls, name, bases, dic)
  32.         instance.ids = X509NameMeta.long_names.values()
  33.         for long_name, short_name in X509NameMeta.long_names.items():
  34.             ## Map a long_name property to the short_name attribute
  35.             cls.add_property(instance, long_name, short_name)
  36.         return instance
  37.     def add_property(instance, name, short_name):
  38.         setattr(instance, name, property(lambda self: getattr(self, short_name, None)))
  39.  
  40.  
  41. class X509Name(str):
  42.     __metaclass__ = X509NameMeta
  43.  
  44.     def __init__(self, dname):
  45.         str.__init__(self)
  46.         pairs = [x.replace('\,', ',') for x in re.split(r'(?<!\\),\s*', dname)]
  47.         for pair in pairs:
  48.             try:
  49.                 name, value = pair.split('=', 1)
  50.             except ValueError:
  51.                 raise ValueError("Invalid X509 distinguished name: %s" % dname)
  52.             str.__setattr__(self, name, value)
  53.         for name in X509Name.ids:
  54.             if not hasattr(self, name):
  55.                 str.__setattr__(self, name, None)
  56.     def __setattr__(self, name, value):
  57.         if name in X509Name.ids:
  58.             raise AttributeError("can't set attribute")
  59.         str.__setattr__(self, name, value)
  60.  
  61.  
  62. class AlternativeNames(object):
  63.     __slots__ = {'dns': GNUTLS_SAN_DNSNAME, 'email': GNUTLS_SAN_RFC822NAME, 'uri': GNUTLS_SAN_URI,
  64.                  'ip': GNUTLS_SAN_IPADDRESS, 'other': GNUTLS_SAN_OTHERNAME, 'dn': GNUTLS_SAN_DN}
  65.     def __init__(self, names):
  66.         object.__init__(self)
  67.         for name, key in self.__slots__.iteritems():
  68.             setattr(self, name, tuple(names.get(key, ())))
  69.  
  70.  
  71. class X509Certificate(object):
  72.  
  73.     def __new__(cls, *args, **kwargs):
  74.         instance = object.__new__(cls)
  75.         instance.__deinit = gnutls_x509_crt_deinit
  76.         instance._c_object = gnutls_x509_crt_t()
  77.         instance._alternative_names = None
  78.         return instance
  79.  
  80.     @method_args(str, one_of(X509_FMT_PEM, X509_FMT_DER))
  81.     def __init__(self, buf, format=X509_FMT_PEM):
  82.         gnutls_x509_crt_init(byref(self._c_object))
  83.         data = gnutls_datum_t(cast(c_char_p(buf), POINTER(c_ubyte)), c_uint(len(buf)))
  84.         gnutls_x509_crt_import(self._c_object, byref(data), format)
  85.  
  86.     def __del__(self):
  87.         self.__deinit(self._c_object)
  88.  
  89.     @property
  90.     def subject(self):
  91.         size = c_size_t(256)
  92.         dname = create_string_buffer(size.value)
  93.         try:
  94.             gnutls_x509_crt_get_dn(self._c_object, dname, byref(size))
  95.         except MemoryError:
  96.             dname = create_string_buffer(size.value)
  97.             gnutls_x509_crt_get_dn(self._c_object, dname, byref(size))
  98.         return X509Name(dname.value)
  99.  
  100.     @property
  101.     def issuer(self):
  102.         size = c_size_t(256)
  103.         dname = create_string_buffer(size.value)
  104.         try:
  105.             gnutls_x509_crt_get_issuer_dn(self._c_object, dname, byref(size))
  106.         except MemoryError:
  107.             dname = create_string_buffer(size.value)
  108.             gnutls_x509_crt_get_issuer_dn(self._c_object, dname, byref(size))
  109.         return X509Name(dname.value)
  110.  
  111.     @property
  112.     def alternative_names(self):
  113.         if self._alternative_names is not None:
  114.             return self._alternative_names
  115.         names = {}
  116.         size = c_size_t(256)
  117.         alt_name = create_string_buffer(size.value)
  118.         for i in xrange(65536):
  119.             try:
  120.                 name_type = gnutls_x509_crt_get_subject_alt_name(self._c_object, i, alt_name, byref(size), None)
  121.             except RequestedDataNotAvailable:
  122.                 break
  123.             except MemoryError:
  124.                 alt_name = create_string_buffer(size.value)
  125.                 name_type = gnutls_x509_crt_get_subject_alt_name(self._c_object, i, alt_name, byref(size), None)
  126.             names.setdefault(name_type, []).append(alt_name.value)
  127.         self._alternative_names = AlternativeNames(names)
  128.         return self._alternative_names
  129.  
  130.     @property
  131.     def serial_number(self):
  132.         size = c_size_t(1)
  133.         serial = c_ulong()
  134.         try:
  135.             gnutls_x509_crt_get_serial(self._c_object, cast(byref(serial), c_void_p), byref(size))
  136.         except MemoryError:
  137.             import struct, sys
  138.             serial = create_string_buffer(size.value * sizeof(c_void_p))
  139.             gnutls_x509_crt_get_serial(self._c_object, cast(serial, c_void_p), byref(size))
  140.             pad = size.value * sizeof(c_void_p) - len(serial.value)
  141.             format = '@%dL' % size.value
  142.             numbers = list(struct.unpack(format, serial.value + pad*'\x00'))
  143.             if sys.byteorder == 'little':
  144.                 numbers.reverse()
  145.             number = 0
  146.             offset = sizeof(c_void_p) * 8
  147.             for n in numbers:
  148.                 number = (number<<offset) + n
  149.             return number
  150.         else:
  151.             return serial.value
  152.  
  153.     @property
  154.     def activation_time(self):
  155.         return gnutls_x509_crt_get_activation_time(self._c_object)
  156.  
  157.     @property
  158.     def expiration_time(self):
  159.         return gnutls_x509_crt_get_expiration_time(self._c_object)
  160.  
  161.     @property
  162.     def version(self):
  163.         return gnutls_x509_crt_get_version(self._c_object)
  164.  
  165.     #@method_args(X509Certificate)
  166.     def has_issuer(self, issuer):
  167.         """Return True if the certificate was issued by the given issuer, False otherwise."""
  168.         if not isinstance(issuer, X509Certificate):
  169.             raise TypeError("issuer must be an X509Certificate object")
  170.         return bool(gnutls_x509_crt_check_issuer(self._c_object, issuer._c_object))
  171.  
  172.     @method_args(str)
  173.     def has_hostname(self, hostname):
  174.         """Return True if the hostname matches the DNSName/IPAddress subject alternative name extension
  175.            of this certificate, False otherwise."""
  176.         ## For details see http://www.ietf.org/rfc/rfc2459.txt, section 4.2.1.7 Subject Alternative Name
  177.         return bool(gnutls_x509_crt_check_hostname(self._c_object, hostname))
  178.  
  179.     def check_issuer(self, issuer):
  180.         """Raise CertificateError if certificate was not issued by the given issuer"""
  181.         if not self.has_issuer(issuer):
  182.             raise CertificateError("certificate issuer doesn't match")
  183.  
  184.     def check_hostname(self, hostname):
  185.         """Raise CertificateError if the certificate DNSName/IPAddress subject alternative name extension
  186.            doesn't match the given hostname"""
  187.         if not self.has_hostname(hostname):
  188.             raise CertificateError("certificate doesn't match hostname")
  189.  
  190.  
  191. class X509PrivateKey(object):
  192.     def __new__(cls, *args, **kwargs):
  193.         instance = object.__new__(cls)
  194.         instance.__deinit = gnutls_x509_privkey_deinit
  195.         instance._c_object = gnutls_x509_privkey_t()
  196.         return instance
  197.  
  198.     @method_args(str, one_of(X509_FMT_PEM, X509_FMT_DER))
  199.     def __init__(self, buf, format=X509_FMT_PEM):
  200.         gnutls_x509_privkey_init(byref(self._c_object))
  201.         data = gnutls_datum_t(cast(c_char_p(buf), POINTER(c_ubyte)), c_uint(len(buf)))
  202.         gnutls_x509_privkey_import(self._c_object, byref(data), format)
  203.  
  204.     def __del__(self):
  205.         self.__deinit(self._c_object)
  206.  
  207.  
  208. class X509Identity(object):
  209.     """A X509 identity represents a X509 certificate and private key pair"""
  210.     
  211.     __slots__ = ('cert', 'key')
  212.     
  213.     @method_args(X509Certificate, X509PrivateKey)
  214.     def __init__(self, cert, key):
  215.         self.cert = cert
  216.         self.key = key
  217.     
  218.     def __setattr__(self, name, value):
  219.         if name in self.__slots__ and hasattr(self, name):
  220.             raise AttributeError("can't set attribute")
  221.         object.__setattr__(self, name, value)
  222.  
  223.     def __delattr__(self, name):
  224.         if name in self.__slots__:
  225.             raise AttributeError("can't delete attribute")
  226.         object.__delattr__(self, name)
  227.  
  228.  
  229. class X509CRL(object):
  230.     def __new__(cls, *args, **kwargs):
  231.         instance = object.__new__(cls)
  232.         instance.__deinit = gnutls_x509_crl_deinit
  233.         instance._c_object = gnutls_x509_crl_t()
  234.         return instance
  235.  
  236.     @method_args(str, one_of(X509_FMT_PEM, X509_FMT_DER))
  237.     def __init__(self, buf, format=X509_FMT_PEM):
  238.         gnutls_x509_crl_init(byref(self._c_object))
  239.         data = gnutls_datum_t(cast(c_char_p(buf), POINTER(c_ubyte)), c_uint(len(buf)))
  240.         gnutls_x509_crl_import(self._c_object, byref(data), format)
  241.  
  242.     def __del__(self):
  243.         self.__deinit(self._c_object)
  244.  
  245.     @property
  246.     def count(self):
  247.         return gnutls_x509_crl_get_crt_count(self._c_object)
  248.  
  249.     @property
  250.     def version(self):
  251.         return gnutls_x509_crl_get_version(self._c_object)
  252.  
  253.     @property
  254.     def issuer(self):
  255.         size = c_size_t(256)
  256.         dname = create_string_buffer(size.value)
  257.         try:
  258.             gnutls_x509_crl_get_issuer_dn(self._c_object, dname, byref(size))
  259.         except MemoryError:
  260.             dname = create_string_buffer(size.value)
  261.             gnutls_x509_crl_get_issuer_dn(self._c_object, dname, byref(size))
  262.         return X509Name(dname.value)
  263.  
  264.     @method_args(X509Certificate)
  265.     def is_revoked(self, cert):
  266.         """Return True if certificate is revoked, False otherwise"""
  267.         return bool(gnutls_x509_crt_check_revocation(cert._c_object, byref(self._c_object), 1))
  268.  
  269.     def check_revocation(self, cert, cert_name='certificate'):
  270.         """Raise CertificateRevokedError if the given certificate is revoked"""
  271.         if self.is_revoked(cert):
  272.             raise CertificateRevokedError("%s was revoked" % cert_name)
  273.  
  274.  
  275. class DHParams(object):
  276.     def __new__(cls, *args, **kwargs):
  277.         instance = object.__new__(cls)
  278.         instance.__deinit = gnutls_dh_params_deinit
  279.         instance._c_object = gnutls_dh_params_t()
  280.         return instance
  281.  
  282.     @method_args(int)
  283.     def __init__(self, bits=1024):
  284.         gnutls_dh_params_init(byref(self._c_object))
  285.         gnutls_dh_params_generate2(self._c_object, bits)
  286.  
  287.     def __get__(self, obj, type_=None):
  288.         return self._c_object
  289.  
  290.     def __set__(self, obj, value):
  291.         raise AttributeError("Read-only attribute")
  292.  
  293.     def __del__(self):
  294.         self.__deinit(self._c_object)
  295.  
  296.  
  297. class RSAParams(object):
  298.     def __new__(cls, *args, **kwargs):
  299.         instance = object.__new__(cls)
  300.         instance.__deinit = gnutls_rsa_params_deinit
  301.         instance._c_object = gnutls_rsa_params_t()
  302.         return instance
  303.  
  304.     @method_args(int)
  305.     def __init__(self, bits=1024):
  306.         gnutls_rsa_params_init(byref(self._c_object))
  307.         gnutls_rsa_params_generate2(self._c_object, bits)
  308.  
  309.     def __get__(self, obj, type_=None):
  310.         return self._c_object
  311.  
  312.     def __set__(self, obj, value):
  313.         raise AttributeError("Read-only attribute")
  314.  
  315.     def __del__(self):
  316.         self.__deinit(self._c_object)
  317.  
  318.